package dao

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/olivere/elastic/v7"
	"listenboos-common/kafka/model"
	"strconv"
	"strings"
)

type SuggestElasticDAO struct {
	Client *elastic.Client
}

func NewSuggestElasticDAO() *SuggestElasticDAO {
	opts := []elastic.ClientOptionFunc{
		elastic.SetURL("http://192.168.2.9:9200"),
		elastic.SetSniff(false), // 禁用 sniffing（在生产环境中应启用）
	}
	client, err := elastic.NewClient(opts...)
	if err != nil {
		panic(err)
	}

	return &SuggestElasticDAO{Client: client}
}
func (h *SuggestElasticDAO) InputAlbum(ctx context.Context, art model.SuggestInfo) error {
	doc := map[string]interface{}{
		"id":              art.Id,
		"title":           art.Title,
		"keyword":         map[string]interface{}{"input": art.Keyword}, // completion字段需要特殊的格式
		"keywordPinyin":   map[string]interface{}{"input": art.KeywordPinyin},
		"keywordSequence": map[string]interface{}{"input": art.KeywordSequence},
	}

	_, err := h.Client.Index().
		Index(Suggest).
		Id(strconv.FormatInt(art.Id, 10)).
		BodyJson(doc).Do(ctx)
	return err
}
func (h *SuggestElasticDAO) SuggestSearch(ctx context.Context, sug string) (res []string, err error) {
	// 创建模糊查询，针对 title 字段
	//fuzzyQuery := elastic.NewFuzzyQuery("title", sug).
	//	Fuzziness("AUTO")

	// 创建一个布尔查询，将模糊查询添加到其中
	//boolQuery := elastic.NewBoolQuery().Must(fuzzyQuery)
	// 这个是关键字
	cs := elastic.NewContextSuggester("suggestionKeyword")
	cs = cs.Prefix(sug)
	cs = cs.Field("keyword")
	searchResult, err := h.Client.Search().
		Index(Suggest).
		Suggester(cs). //Query(boolQuery).
		Pretty(true).
		Do(context.Background())
	if err != nil {
		fmt.Println(err)
	}
	if suggest, found := searchResult.Suggest["suggestionKeyword"]; found {
		// 遍历建议选项
		for _, option := range suggest[0].Options {
			//fmt.Printf("Suggested term: %s\n", option.Source) // 输出建议的术语
			k := model.SuggestInfo{}
			err = json.Unmarshal(option.Source, &k)
			res = append(res, k.Title)
		}
	}
	// 查首字母
	pyin := elastic.NewContextSuggester("suggestionKeywordPinyin")
	pyin = pyin.Prefix(sug)
	pyin = pyin.Field("keywordPinyin")
	resp, err := h.Client.Search().
		Index(Suggest).
		Suggester(pyin). //Query(boolQuery).
		Pretty(true).
		Do(context.Background())
	if suggest, found := resp.Suggest["suggestionKeywordPinyin"]; found {
		// 遍历建议选项
		for _, option := range suggest[0].Options {
			//fmt.Printf("Suggested term: %s\n", option.Source) // 输出建议的术语
			k := model.SuggestInfo{}
			err = json.Unmarshal(option.Source, &k)
			res = append(res, k.Title)
		}
	}
	pyin = elastic.NewContextSuggester("suggestionKeywordSequence")
	pyin = pyin.Prefix(sug)
	pyin = pyin.Field("keywordSequence")
	resp, err = h.Client.Search().
		Index(Suggest).
		Suggester(pyin). //Query(boolQuery).
		Pretty(true).
		Do(context.Background())
	if err != nil {
		return nil, err
	}
	if suggest, found := resp.Suggest["suggestionKeywordSequence"]; found {
		// 遍历建议选项
		for _, option := range suggest[0].Options {
			//fmt.Printf("Suggested term: %s\n", option.Source) // 输出建议的术语
			k := model.SuggestInfo{}
			err = json.Unmarshal(option.Source, &k)
			res = append(res, k.Title)
		}
	}
	// TODO:这里还没有进行测试
	if len(res) < 5 {
		// 数量小于5 我们查询专辑补
		queryString := strings.Join([]string{sug}, " ")
		query := elastic.NewBoolQuery().Must(
			elastic.NewBoolQuery().Should(
				elastic.NewMatchQuery("title", queryString)))
		resp, err := h.Client.Search(suggest).Query(query).Do(ctx)
		if err != nil {
			return nil, err
		}
		for _, hit := range resp.Hits.Hits {
			var ele model.SuggestInfo
			err = json.Unmarshal(hit.Source, &ele)
			res = append(res, ele.Title)
		}
	}
	return res, nil
}
